import type { ComponentInternalInstance } from "@vue/runtime-core";
import Decimal from "decimal.js";
import { useCurrentLang, useMessage, useNotify, useQueue, useToast, useTouch, useUpload } from "wot-design-uni";

/**
 * @description  useCallPhone 一键拨打电话
 * @param {string} phone 传入手机号
 * @author 花东红
 * @time 2025/3/8
 */
export const useCallPhone = (phone: string) => {
  if (!phone) return;
  const getSystemInfoSync = uni.getSystemInfoSync();
  if (getSystemInfoSync.platform === "ios") return uni.makePhoneCall({ phoneNumber: phone }).catch(() => {});
  uni.showActionSheet({
    itemList: [phone, "呼叫"],
    success: (resp) => {
      if (resp.tapIndex === 1) {
        uni.makePhoneCall({ phoneNumber: phone }).catch(() => {});
      }
    }
  });
};

/**
 * @description  useGetSystemPlatform 获取当前运行平台
 * @description 平台标识：mp-weixin | web | app | mp-alipay | mp-baidu | mp-toutiao | mp-qq | mp-lark | mp-kuaishou | mp-jd
 * @author 花东红
 * @time 2025/3/8
 */
export const useGetSystemPlatform = (): Utils.useGetSystemPlatformReturnType => {
  const platform = (uni.getAppBaseInfo() as UniNamespace.GetSystemInfoResult).uniPlatform as Utils.useGetSystemPlatformReturnType["platform"];
  return {
    platform,
    isH5: platform === "web",
    isApp: platform === "app",
    isMp: platform.startsWith("mp-"),
    isMpWeixin: platform.startsWith("mp-weixin"),
    isMpAplipay: platform.startsWith("mp-alipay"),
    isMpToutiao: platform.startsWith("mp-toutiao")
  };
};

/**
 * @description  useGetWChartEnv 获取微信小程序当前运行环境,只能在微信小程序中使用
 * @returns {string} develop | trial | release
 * @author 花东红
 * @time 2025/3/8
 */
export const useGetWChartEnv = (): UniNamespace.MiniProgram["envVersion"] => {
  return uni.getAccountInfoSync().miniProgram.envVersion;
};

/**
 * @description  useGenerateUUID 生成随机UUID
 * @param {number} length 生成的UUID长度
 * @author 花东红
 * @time 2025/3/8
 */
export const useGenerateUUID = (length: number = 16) => {
  const S4 = () => (((1 + Math.random()) * 0x10000) | 0).toString(length).substring(1);
  return `${S4() + S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}`;
};

/**
 * @description  useFormatNumber 千分位格式化
 * @param {string | number} price 价格
 * @author 花东红
 * @time 2025/3/20
 */
export const useFormatNumber = (price: string | number) => {
  if (!price) return "0.00";
  return price.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
};

/**
 * @description useFormatPriceCustom 千分位格式化
 * @param {string | number} price 价格
 * @param {number} precision 小数精度
 * @author 花东红
 * @time 2025/3/20
 */
export const useFormatPriceCustom = (price: string | number, precision: number = 2) => {
  if (!price) return "0.00";
  if (Number.parseFloat(price as string) >= 10000) {
    // 转换为“万”并保留小数点后两位
    return `${new Decimal(price).div(new Decimal(10000)).toFixed(precision)}万`;
  } else {
    // 直接添加千分位
    return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }
};

/**
 * @description useSplitPrice 处理根据小数点拆分价格
 * @param {string | number} price 价格
 * @param {boolean} point 处理后是否需要小数点
 * @author 花东红
 * @time 2025/3/20
 */
export const useSplitPrice = (price: string | number, point: boolean = true) => {
  if (!price) return { integer: "", fractional: "" };
  const [integer, fractional] = price.toString().split(".");

  return {
    integer, // 整数
    fractional: fractional ? (point ? `.${fractional}` : fractional) : "" // 小数
  };
};

/**
 * @description useFilterEmptyParams 过滤掉为空的请求参数
 * @param {Record<string, any>} data 接口请求参数
 * @author 花东红
 * @time 2024/7/15
 */
export const useFilterEmptyParams = (data: Record<string, any>) => {
  if (!Object.keys(data).length) return {};
  return Object.entries(data).reduce((acc, [key, value]) => {
    if (value !== null && value !== undefined && value !== "") {
      // @ts-expect-error check value type
      acc[key] = value;
    }
    return acc;
  }, {});
};

/**
 * @description  useCopyContent 一键复制文本内容
 * @param {string} content 传入需要复制的文本内容
 * @author 花东红
 * @time 2025/3/8
 */
export const useCopyContent = (content: string) => {
  if (!content) return;
  uni.setClipboardData({
    data: content,
    success: () => {
      uni.showToast({ title: "复制成功", icon: "none" }).catch(() => {});
    }
  });
};

/**
 * @description usePreviewFile 预览文件
 * @param url 文件地址, 例如："https://example.com/file.pdf"
 * @param fileType 文件类型 "doc" | "xls" | "ppt" | "pdf" | "docx" | "xlsx" | "pptx" , 默认为 "pdf"
 * @author 花东红
 * @time 2025/8/8
 */
export const usePreviewFile = (url: string, fileType: "doc" | "xls" | "ppt" | "pdf" | "docx" | "xlsx" | "pptx" = "pdf") => {
  uni.downloadFile({
    url,
    success: (res) => {
      if (res.statusCode === 200) {
        uni.openDocument({
          filePath: res.tempFilePath,
          fileType,
          showMenu: true,
          fail: (err) => console.error("打开失败", err)
        });
      }
    },
    fail: (err) => console.error("下载失败", err)
  });
};

/**
 * @description useGetNodeElement 获取 dom 节点信息
 * @param proxy 当前页面实例, const { proxy } = getCurrentInstance();
 * @param selectorElement 节点选择器, 例如："#id, .id"
 * @author 花东红
 * @time 2025/8/8
 */
export const useGetNodeElement = (proxy: ComponentInternalInstance["proxy"], selectorElement: string): Promise<UniNamespace.NodeInfo> => {
  return new Promise((resolve) => {
    uni
      .createSelectorQuery()
      .in(proxy)
      .select(selectorElement)
      .boundingClientRect((rect: Record<string, any>) => {
        resolve(rect || {});
      })
      .exec();
  });
};

/**
 * @description checkStatus 校验网络请求状态码
 * @param {number} status
 * @author 花东红
 * @time 2025/8/7
 */
export const checkStatus = (status: number) => {
  const codeMap: Record<string, string> = {
    400: "请求失败！请您稍后重试",
    403: "当前账号无权限访问！",
    404: "你所访问的接口不存在！",
    405: "请求方式错误，请您稍后重试",
    408: "请求超时，请您稍后重试",
    500: "服务异常，请您稍后重试",
    502: "网关错误，请您稍后重试",
    503: "服务不可用，请您稍后重试",
    504: "网关超时，请您稍后重试"
  };
  if (codeMap[status]) {
    uni.showToast({ title: codeMap[status], icon: "none" }).catch(() => {});
    return;
  }
  uni.showToast({ title: "请求失败，请您稍后重试", icon: "none" }).catch(() => {});
};

/**
 * @description useRegisterWotHooks 在主包内注册挂载 Wot 组件库的工具函数，避免 hooks 不生效
 * @author 花东红
 * @time 2025/8/14
 */
export const useRegisterWotHooks = () => {
  const toast = useToast();
  const notify = useNotify();
  const message = useMessage();
  const touch = useTouch();
  const upload = useUpload();
  const queue = useQueue();
  const lang = useCurrentLang();
  return { toast, notify, message, touch, upload, queue, lang };
};
